;------------------------------------------------------------------------------ ; ; UCODE FOR BARE 800 BPI, 125 IPS TAPE DRIVE ; ;------------------------------------------------------------------------------ ;TAPE DELAY CONSTANTS .REPEAT 0 [ ;45 IPS VALUES TP-RD-STRT-DLY = 59. TP-BOT-DLY = 34. TP-GAP-DETECT-DLY = 61. TP-EOR-DLY = 18. TP-WR-STRT-DLY = 36. TP-MBOOT-GAP-DLY = 14. ] .REPEAT 1 [ ;125 IPS VALUES TP-RD-STRT-DLY = 20. TP-BOT-DLY = 12. TP-GAP-DETECT-DLY = 22. TP-EOR-DLY = 7. TP-WR-STRT-DLY = 13. TP-MBOOT-GAP-DLY = 9. ] ;TAPE READING AND WRITING CODE ; A-MEM USAGE: ; 0 DISPATCH ADDR. TPMODE = 1 ;MODE BITS (SEE BELOWS) ; 4 COPY OF HDWR CTRL REGISTER (WRITE) ; 5 READ ERROR FLAGS ; 6 TEMP WITHIN TRP2 (HOLDS TP PAR ERR FLG) ; WHEN WRITING, HOLDS ODD-EVEN WC FLAG. ; ;Mode bits: ; Bit 35 Industry compatable mode (4 bytes/word) ; (Otherwise, PDP-10 dump mode) ; ;PDP-10 Dump mode ; ------------------------------------------------------------------------ ; | | | | | | ; | Byte 1 | Byte 2 | Byte 3 | Byte 4 | | ; | | | | | | ; ------------------------------------------------------------------------ ; | | ; V V ; ----------------- ; | | Bits | ; | 0 | 32:35 | ; | Byte 5 | ; ----------------- ; ;Industry Compatable Mode ; ------------------------------------------------------------------------ ; | | | | | | ; | Byte 1 | Byte 2 | Byte 3 | Byte 4 | 0 | ; | | | | | | ; ------------------------------------------------------------------------ ; ;727 - OBSOLETE VERSION OF READ .PAIR UIOTRP[MUUO] $ TAPERD: D[CONST 22] ROT[6] DEST[IOD] SPEC[IOB-OUT] NORM PUSHJ[TPRDGO] $ D[MASK 17.] DEST[IR-ADR] PUSHJ[TRP2] NORM $ ;MOVE STATUS INTO AC. ALU[Q] DEST[AC] ACSEL[AC] MAPF[2] JUMP[MAIN] CYLEN[IOB-OUT] $ ; TPRDGO -- CALLED AS TAPE MOTION IS STARTED. WAITS FOR ; FIRST GAP TO PASS. TPRDGO: MAPF[2] D[CONST 2] ROT[35. - 5] DEST[Q] C800 $ ;FIRST SET "CTL WD SEL" TO 1 (SELECT TP RD DAT) SPEC[IOB-OUT] D[CONST 1] ROT[35. - 28.] ALU[DORQ] DEST[IOD] NORM $ ;..ALSO SET THE "IN" BIT. ;NOW WAIT 8.3MSEC FOR 45IPS TAPE (38MSEC IF AT BOT). ; (GET 2*DELAY-COUNT) MAPF[4] D[CONST TP-RD-STRT-DLY] ROT[9.] DEST[AR] CYLEN[IOB-OUT] SPEC[IOB-IN] PUSHJ[TPBOTD] $ ;HANDLE BOT CASE. D[AR] ROT[35.] MASK[20.] DEST[AR] NORM $ ;GET DELAY-COUNT ;IF FOLLOWING CYLEN IS MADE 1000, DMA XFERS LOSE. D[AR] ALU[D-1] DEST[AR] COND[-OBUS=0] JUMP[.] C550 $ SPEC[IOB-IN] D[CONST 40] ROT[14.] DEST[Q] NORM $ ;CLEAR DATA RDY FLAGI, GET TIMOUT COUNT IN Q MAPF[1] NORM ALU[0] DEST[5] DEST-A-MEM $ ;CLR ERROR REG P1: SPEC[IOB-IN] C550 $ ;NOW WAIT FOR FIRST BYTE D[IOD] DEST[HOLD] MAPF[2] C550 $ D[MEM] ROT[33] MASK[1] COND[-OBUS=0] C550 POPJ $ ALU[Q-1] DEST[Q] COND[-OBUS=0] JUMP[P1] C550 $ ALU[0] DEST[IOD] SPEC[IOB-OUT] NORM $ ;TIMEOUT... STOP TAPE. MAPF[2] D[CONST 41] ROT[36] DEST[Q] JPOP[TNRP3] NORM $ ;ABORT ;IF WE ARE AT BOT, SET DELAY TIME FOR LARGE GAP. TPBOTD: D[IOD] MAPF[4] ROT[15.] DEST[Q] CYLEN[IOB-IN] $ ALU[Q] OBUS<0 POPJ C550 $ ;RET IF NOT BOT TP3IDL: D[CONST TP-BOT-DLY] ROT[12.] DEST[AR] NORM POPJ $ ;ABOUT 77MSEC ;READ A RECORD. STORE UP TO C(IR-ADR) WORDS. TRP2: ALU[0] DEST[6] DEST-A-MEM NORM PUSHJ[TRBA] $ JUMP[TRP2B] NORM $ ;Already have first byte, Jump into loop ;This loop is repeated for each word. At end-of-record, TRBYTE terminates ;the loop by popping off return address and returning to the routine that ;requested that a record be read. TRP2A: ALU[0] DEST[6] DEST-A-MEM PUSHJ[TRBYTE] NORM $ TRP2B: D[MEM] ROT[34] DEST[Q] PUSHJ[TRBYTE] NORM $ D[MEM] ROT[24] ALU[DORQ] DEST[Q] PUSHJ[TRBYTE] NORM $ D[10 + TPMODE] MASK[1] NORM COND[-OBUS=0] JUMP[TRP2D] $ ;While we have the time to decide, handle last ;byte of industry-compatable mode differently D[MEM] ROT[14] ALU[DORQ] DEST[Q] PUSHJ[TRBYTE] NORM $ D[MEM] ROT[4] ALU[DORQ] DEST[Q] PUSHJ[TRBYTE] NORM $ D[IR] MASK[18.] ALU[D-1] DEST[IR-ADR] COND[OBUS18] JUMP[TRP2A] C600 $ ;Decrement count. If word count exhausted, finish reading ;record but don't write anything. D[MEM] MASK[4] ALU[DORQ] DEST[MEMSTO] NORM $ ;Note that it is presumed here that the operating system has ;already dealt with page faults before we get here. TRP2C: D[16] DEST[Q] NORM$ D[15] ALU[DORQ] DEST[Q] NORM $ ;GET ERROR FLG FOR WORD. ALU[Q] DEST[5] DEST-A-MEM NORM $ D[MA] ALU[D+1] DEST[MA] JUMP[TRP2A] NORM $ ;Special for industry compatable mode. TRP2D: D[MEM] ROT[14] ALU[DORQ] DEST[Q] PUSHJ[TRBYTE] NORM $ ;Deposit byte 3, get byte 4 D[IR] MASK[18.] ALU[D-1] DEST[IR-ADR] COND[OBUS18] JUMP[TRP2A] C600 $ ;Decrement count. If word count exhausted, finish reading ;record but don't write anything. D[MEM] ROT[4] ALU[DORQ] DEST[MEMSTO] NORM JUMP[TRP2C] $ ;Deposit byte 4 (last) and store away. Rejoin regular program. ;READ 1 BYTE. IF ERROR, EOR, EOF, SET Q_2,HIGHEST LOC WRITTEN+1,1 & POP ; ONE OFF THE STACK AND RETURN. IF BYTE SUCCESSFULLY ; READ, JUST RETURN WITH BYTE IN HOLD. TRBYTE: D[CONST TP-GAP-DETECT-DLY] LLOAD NORM $ TRB2: SPEC[IOB-IN] LOOP[TRB1] C550 $ D[CONST TP-EOR-DLY] ROT[6] LLOAD C550 $ LOOP[.] C550 $ SPEC[IOB-IN] C550 $ MAPF[1] D[AR] ROT[42] MASK[21] ; IS RECORD <4 CHRS (MEAN- COND[-OBUS=0] JUMP[TREOR] C550 $ ; ING END-OF-FILE) ? D[CONST 60] ROT[36] DEST[5] DEST-A-MEM NORM $ ;YES ALU[Q] DEST[AR] NORM $ D[AR] ROT[28.] DEST[Q] JPOP[TRDONE] NORM $ TREOR: ALU[Q] DEST[7] DEST-A-MEM NORM $ ;SAVE CHECK CHRS. D[MA] MASK[24] DEST[Q] NORM JPOP[TRDONE] $ ;ENDX OF REC. TRB1: D[IOD] ALU[NOTD] DEST[HOLD] MAPF[2] LONG $ C550 $ ;GIVE DMA DEVICES A CHANCE AT THE BUS !! D[MEM] ROT[33] MASK[1] COND[-OBUS=0] JUMP[TRB2] C550 $ TRBA: SPEC[IOB-IN] D[AR] ALU[D+1] DEST[AR] NORM $ MAPF[2] SPEC[IOB-IN] D[IOD] ALU[NOTD] DEST[HOLD] C800 $ MAPF[1] D[MEM] ROT[31] C550 OBUS<0 JUMP[TRERR] $ ;TEST THE ERROR BIT. TRB4: D[MEM] MASK[10] DEST[HOLD] POPJ NORM $ TRDONE: D[CONST 0] DEST[IOD] SPEC[IOB-OUT] NORM $ ;STOP TAPE. ;COMBINE ERROR CODE WITH MA AND RETURN (UPLEVEL). MAPF[2] CYLEN[IOB-OUT] D[15] ALU[DORQ] DEST[Q] POPJ $ ;BYTE PARITY ERROR - CODE TO AMEM(6), CONT. TRERR: D[CONST 50] ROT[36] DEST[6] DEST-A-MEM NORM JUMP[TRB4] $ ;SET BIT 2 OF ERROR FLAGS. .PAIR UIOTRP[MUUO] $ TAPEMT: ;MTAPE FUNCTIONS. D[MA] DEST[Q] COND[OBUS=0] JUMP[TAPERW] C550 $ ;Start rewinding D[CONST 5] ALU[D-Q] COND[OBUS=0] JUMP[TAPEFR] C550 $ ;Forward space one record D[CONST 6] ALU[D-Q] COND[OBUS=0] JUMP[TAPEBR] C550 $ ;Backspace space one record D[CONST 1] ALU[D-Q] COND[OBUS=0] JUMP[TWREOF] C550 $ ;Write EOF D[CONST 50] ALU[D-Q] COND[OBUS=0] JUMP[TPSETIND] C550 $ ;Code ?, set industry compatable mode. D[CONST 51] ALU[D-Q] COND[OBUS=0] JUMP[TPSETDMP] C550 $ ;Code ?, set PDP-10 dump mode. JUMP[MAIN] $ ;UNKNOWN CODE -- TREAT AS NOP. TWREOF: ALU[0] DEST[MA] NORM PUSHJ[TP3IDL] $ ;SET FLG AND GET D[CONST 0] DEST[6] DEST-A-MEM NORM JUMP[TWEOF] $ ; 3" GAP DLY CNT, THEN GO TO WRITE CODE. TAPERW: ;REWIND D[CONST 6] ROT[6] DEST[IOD] SPEC[IOB-OUT] NORM $ MAPF[2] CYLEN[IOB-OUT] ALU[0] DEST[IOD] SPEC[IOB-OUT] $ MAPF[2] JUMP[MAIN] CYLEN[IOB-OUT] $ TAPEFR: ;SKIP FORWARD ONE RECORD. D[CONST 22] ROT[6] DEST[IOD] SPEC[IOB-OUT] NORM PUSHJ[TPRDGO] $ D[CONST 0] DEST[IR-ADR] PUSHJ[TRP2] NORM $ ;MOVE STATUS INTO AC. ALU[Q] DEST[AC] ACSEL[AC] MAPF[2] JUMP[MAIN] CYLEN[LONG] $ TAPEBR: ;SKIP BACKWARD ONE RECORD. D[CONST 2] ROT[6] DEST[IOD] SPEC[IOB-OUT] CYLEN[LONG] $ MAPF[2] SPEC[IOB-IN] CYLEN[IOB-OUT] $ D[IOD] ROT[18.] MASK[6] DEST[Q] MAPF[4] CYLEN[IOB-IN] $ D[CONST 4] ALU[D&Q] COND[OBUS=0] JUMP[TBRLP] C550 $ ;JUMP IF AT LP D[CONST 12] ROT[6] DEST[IOD] SPEC[IOB-OUT] NORM PUSHJ[TPRDGO] $ D[CONST 0] DEST[IR-ADR] PUSHJ[TRP2] NORM $ ALU[Q] DEST[AC] ACSEL[AC] MAPF[2] JUMP[MAIN] NORM $ TPSETIND: ;Set industry compatable mode D[10 + TPMODE] DEST[Q] NORM $ ;Stupid A-MEM D[CONST 1] ALU[DORQ] DEST[TPMODE] DEST-A-MEM JUMP[MAIN] NORM $ ;Set appropriate bit and done TPSETDMP: ;Set PDP-10 Dump Mode D[10 + TPMODE] DEST[Q] NORM $ ;Stupid A-MEM D[CONST 1] ALU[-D&Q] DEST[TPMODE] DEST-A-MEM JUMP[MAIN] NORM $ ;Clear industry compatable mode and done. TAPERS: ;READ STATUS BITS FROM TAPE DRIVE. D[CONST 2] ROT[6] DEST[IOD] SPEC[IOB-OUT] NORM $ ;; SELECT THE DRIVE. MAPF[2] CYLEN[IOB-OUT] SPEC[IOB-IN] $ MAPF[4] D[IOD] ROT[18.] MASK[6] DEST[Q] CYLEN[IOB-IN] $ D[MASK 6] ALU[D#Q] DEST[MEMSTO] NORM COND[-MA-AC] LBJUMP[SMAIN] $ TBRLP: ALU[0] DEST[IOD] SPEC[IOB-OUT] NORM $ MAPF[6] JUMP[MAIN] CYLEN[IOB-OUT] $ .PAIR UIOTRP[MUUO] $ TAPENR: ;730, AC/COUNT. READ WHOLE RECORD, ;STORING UP TO COUNT WORDS STARTING AT EFF ADR. ;IF AC<>0 RETURN STATUS AS FOR 727. ;SWAP AC AND MA, THEN DO TAPERX. D[MA] DEST[O_AC MA] ACSEL[AC] NORM JUMP[TAPERX] $ .PAIR UIOTRP[MUUO] $ TAPERX: ;732 - (AC) IS START ADDR., E IS # OF WORDS TO READ. D[CONST 22] ROT[6] DEST[IOD] SPEC[IOB-OUT] NORM PUSHJ[TPRDGO] $ ;GET TAPE STARTED. ALU[AC] ACSEL[AC] DEST[MA] PUSHJ[TRP2] NORM $ ;READ REC. ;MOVE STATUS INTO AC. D[IR] COND[-OBUS18] JUMP[TNRP3] C550 $ ; WAS RECORD TOO LONG ? D[CONST 44] ROT[30.] ALU[DORQ] DEST[Q] NORM $ ;YES, SET BIT 3. TNRP3: ALU[Q] DEST[AC] ACSEL[AC] JPOP[MAIN] NORM $ ;NO, NOT TOO LONG. UTAPWR: UIOTRP[MUUO] $ D[CONST 2] ROT[6] DEST[IOD] SPEC[IOB-OUT] NORM JUMP[TAPEWR] $ ;Copy of thing in dispatch TAPEWR: ;731, AC/ADR, E/+COUNT. WRITE RECORD OF +COUNT ; WORDS, DATA FROM ADR. ;SET AC:=0 IF OPERATION COMPLETED SUCCESSFULLY. ; SET AC:= + HIGHEST -10 ADR READ IF REACHED ; EOT DURING OPERATION (CURRENTLY THIS IS THE ONLY ; ERROR CONDITION.) ALU[0] DEST[AR] SPEC[IOB-IN] MAPF[2] CYLEN[IOB-OUT] PUSHJ[TPBOTD] $ ;GET 3.5 IN. DLY CNT IN AR IFF AT BOT D[MA] MASK[1] ALU[NOTD] DEST[6] DEST-A-MEM NORM $ ;SAVE LSB OF WC ;### AR HOLDING GOOD STUFF BETWEEN HERE AND TPWR2. ############# TWEOF: ;CLEAR FLAG WHICH WHEN DONE WILL SAY IF PASSED PHYSICAL EOT. ALU[0] DEST[5] DEST-A-MEM NORM $ ;TP WR CLK:=-97. D[CONST 76] ROT[24] DEST[Q] SHORT $ D[CONST 37] ROT[16] ALU[DORQ] DEST[Q] NORM $ D[CONST 1] ROT[41] ALU[DORQ] DEST[IOD] SPEC[IOB-OUT] NORM $ ;-CTL WD SEL:=1,1; DISABLE TP I WARS D[CONST 3] ROT[35. - 5] DEST[Q] MAPF[1] CYLEN[IOB-OUT] $ D[CONST 1] ROT[35. - 26.] ALU[DORQ] DEST[4] DEST-A-MEM NORM $ D[14] DEST[IOD] SPEC[IOB-OUT] NORM $ MAPF[4] CYLEN[IOB-OUT] $ ;SEND TP MR, TP CLEAR LPCC D[CONST 1] ROT[40] DEST[Q] NORM $ D[CONST 1] ROT[32] ALU[DORQ] DEST[IOD] SPEC[IOB-OUT] NORM $ MAPF[1] CYLEN[IOB-OUT] $ ;SET SWS, SLT. D[CONST 3] ROT[6] DEST[IOD] SPEC[IOB-OUT] NORM $ ;SET SFC, SWS, SLT. MAPF[2] D[CONST 23] ROT[6] DEST[IOD] SPEC[IOB-OUT] CYLEN[IOB-OUT] $ MAPF[2] CYLEN[IOB-OUT] D[CONST TP-WR-STRT-DLY] ROT[9.] DEST[Q] $ ;GET 10.1MSEC DLY ;####### SEE ABOVE NOTE ABOUT AR ############################### TPWR2: D[AR] ALU[D+Q] DEST[AR] SHORT $ ;GET TOTAL DELAY ;SPACE OVER GAP (10.1 MSEC, + ABOUT .077 SEC IFF AT BOT) ;IF FOLLOWING CYLEN IS MADE 1000, DMA XFERS LOSE. D[AR] ALU[D-1] DEST[AR] COND[-OBUS=0] JUMP[.] C550 $ ;START WRITE CLOCK. D[14] DEST[Q] SHORT $ D[CONST 3] ROT[35. - 10.] ALU[DORQ] DEST[4] DEST-A-MEM NORM $ D[14] DEST[IOD] SPEC[IOB-OUT] NORM $ D[MA] MASK[18.] DEST[AR] MAPF[4] CYLEN[IOB-OUT] COND[OBUS=0] JUMP[TWEOF1] $ ;WRT FILE MARK ESCAPE ;NEXT WORD. AR:=+COUNT, AC:=ADR. TWNW: ALU[AC] ACSEL[AC] DEST[MA] NORM $ NORM $ ;WAIT FOR FIRST MEMORY FETCH. TWNWL: D[MEM] ROT[8] DEST[Q] PUSHJ[TWBYTE] NORM $ D[MEM] ROT[20] DEST[Q] PUSHJ[TWBYTE] NORM $ D[MEM] ROT[30] DEST[Q] PUSHJ[TWBYTE] NORM $ D[10 + TPMODE] MASK[1] C550 COND[-OBUS=0] JUMP[TWNWI] $ ;Check for industry compatable mode while we have time. D[MEM] ROT[40] DEST[Q] PUSHJ[TWBYTE] NORM $ ;Write last byte of PDP-10 dump mode and decide what's left to do. D[MEM] MASK[4] DEST[Q] PUSHJ[TWBYTE] NORM $ ALU[AC+1] ACSEL[AC] DEST[AC MA] SHORT $ D[AR] ALU[D-1] DEST[AR] COND[-OBUS=0] JUMP[TWNWL] C600 $ ;DONE. WRITE A BLANK FRAME. D[CONST 1] DEST[AR] NORM PUSHJ[TWDLY] $ ;PREPARE TO WRITE CRCC BYTE. D[CONST 50] DEST[Q] SPEC[IOB-IN] NORM JUMP[TWNW1X] $ ;GET CRCC BYTE ;Write last byte of industry compatable mode and decide what's left to do. TWNWI: D[MEM] ROT[40] DEST[Q] PUSHJ[TWBYTE] NORM $ ;Write byte 4, the last byte in this mode ALU[AC+1] ACSEL[AC] DEST[AC MA] SHORT $ D[AR] ALU[D-1] DEST[AR] COND[-OBUS=0] JUMP[TWNWL] C600 $ ;DONE. WRITE A BLANK FRAME. D[CONST 1] DEST[AR] NORM PUSHJ[TWDLY] $ D[CONST 50] DEST[Q] SPEC[IOB-IN] NORM $ ;GET CRCC BYTE ;Previous three lines are same as normal mode and are included separately for ;speed considerations. TWNW1X: MAPF[2] D[IOD] ROT[8] MASK[8] ; ...AND COMP. CERTAIN BITS. ALU[D/#Q] DEST[HOLD] CYLEN[IOB-IN] $ D[CONST 2] DEST[AR] NORM PUSHJ[TWDLY] $ ;WRITE 2 MORE BLANK FRAMES. D[MEM] DEST[Q] NORM $ D[16] MASK[1] DEST[AR] NORM $ D[AR] ROT[43] ALU[-D&Q] DEST[IOD] ;IF WC WAS ODD, WRITE THE SPEC[IOB-IN] NORM PUSHJ[TWBYT1] $ ; CRCC WITH EVEN PAR. ;WAIT 3 BYTE TIMES, SEND WARS TO WRITE LPCC. D[CONST 3] DEST[AR] PUSHJ[TWDLY] $ TWEOFX: D[14] DEST[Q] SHORT $ ;PREPARE TO SEND WARS. D[CONST 1] ROT[11] ALU[-D&Q] DEST[IOD] SPEC[IOB-OUT] NORM $ ;CLEAR TP WR CLK RUN, WARS. TWEXIT: D[14] DEST[Q] MAPF[4] CYLEN[IOB-OUT] $ ;WARS ON. D[CONST 1] ROT[10] ALU[DORQ] DEST[Q] SHORT $ D[CONST 1] ROT[32] ALU[-D&Q] DEST[4] DEST-A-MEM NORM $ D[14] DEST[IOD] SPEC[IOB-OUT] SHORT $ MAPF[4] SPEC[IOB-IN] CYLEN[IOB-OUT] $ ;WARS OFF, WIDTH SHORT + NORM + SHORT +IOB-OUT = 2.0US. ;CHECK TO SEE IF REACHED EOT. D[IOD] DEST[Q] MAPF[4] CYLEN[IOB-IN] $ D[CONST 1] ROT[18.] ALU[D&Q] COND[-OBUS=0] JUMP[TWEX1] $ ALU[-1] DEST[5] NORM DEST-A-MEM $ ;YES, SET FLAG. TWEX1: D[MA] MASK[18.] COND[OBUS=0] C550 JUMP[TWEOF2] $ ;WRT FILE MARK ESCAPE D[15] DEST[AC] ACSEL[AC] NORM $ TWEOF2: ;NOW DELAY FOR 7071 CYCLES (*C550 = 3.89MS = .175" OF TAPE). D[CONST 67] ROT[7] DEST[AR] NORM $ D[AR] ALU[D-1] DEST[AR] COND[-OBUS=0] JUMP[.] C550 $ ;CLEAR SWS, DESELECT TAPE, STOP MOTION. JUMP[TBRLP] $ ;TAPEWR&TWBYTE. WRITE BYTE IN Q. TWBYTE: D[MASK 8] ALU[D&Q] DEST[IOD] SPEC[IOB-IN] NORM $ TWBYT1: D[IOD] DEST[Q] MAPF[4] CYLEN[IOB-IN] SPEC[IOB-OUT] $ D[CONST 1] ROT[18.] ALU[D&Q] COND[OBUS=0] MAPF[14] JUMP[TWEOT] SPEC[IOB-IN] CYLEN[IOB-OUT] $ TWBLP: D[IOD] ROT[21.] DEST[Q] MAPF[2] CYLEN[IOB-IN] $ ALU[Q] -OBUS<0 C600 POPJ $ C550 $ TWBLP1: SPEC[IOB-IN] NORM JUMP[TWBLP] $ ;EOT DETECTED, SET FLAG AND CONTINUE. TWEOT: ALU[-1] DEST[5] DEST-A-MEM JUMP[TWBLP1] NORM $ TWEOF1: D[CONST 23] DEST[Q] NORM $ ;23 IS FILE MARK CHAR. D[CONST 1] ROT[43] ALU[DORQ] DEST[IOD] ;SET BIT 0 IN ORDER TO SPEC[IOB-IN] NORM PUSHJ[TWBYT1] $ ;WRITE IT WITH EVEN PARITY. D[CONST 7] DEST[AR] PUSHJ[TWDLY] NORM $ ;SKIP 7 FRAMES. NORM JUMP[TWEOFX] $ ;COMPLETE THE RECORD AS USUAL. ;TAPEWR&TWDLY. WRITE EVEN PARITY 0S UNTIL TP BYTE DAT COMES ON C(AR) TIMES TWDLY: D[CONST 1] ROT[43] DEST[IOD] SPEC[IOB-OUT] NORM $ PUSHJ[TWBLP] MAPF[14] SPEC[IOB-IN] CYLEN[IOB-OUT] $ D[AR] ALU[D-1] DEST[AR] COND[-OBUS=0] JUMP[TWDLY] C600 $ POPJ NORM $ ;BOOTSTRAP LOADER FOR MACROCODE. .ORG[5000] MBOOT: JUMP[5001] CYLEN[LONG] $ ALU[0] DEST[HI-ABS-MA] PUSHJ[CCLR] NORM $ D[CONST 1] ROT[18.] DEST[HI-ABS-MA] PUSHJ[CCLR] NORM $ D[CONST 7] DEST[DEV-ADR] CYLEN[LONG] $ ;SELECT DEVICE 7. D[CONST 22] ROT[6] DEST[IOD] SPEC[IOB-OUT] NORM PUSHJ[TPRDGO] $ ;SET "SELECT" AND "FORWARD MOTION" ALU[0] DEST[MA HI-ABS-MA] NORM PUSHJ[B3] $ ;MAKE MA RIGHT AND GET FIRST BYTE. NORM JUMP[P2A] $ P2: PUSHJ[BYTE] NORM $ P2A: D[MEM] ROT[34] DEST[Q] PUSHJ[BYTE] NORM $ D[MEM] ROT[24] ALU[DORQ] DEST[Q] PUSHJ[BYTE] NORM $ D[MEM] ROT[14] ALU[DORQ] DEST[Q] PUSHJ[BYTE] NORM $ D[MEM] ROT[4] ALU[DORQ] DEST[Q] PUSHJ[BYTE] NORM $ D[MEM] MASK[4] ALU[DORQ] DEST[MEMSTO] NORM $ D[MA] ALU[D+1] DEST[MA] JUMP[P2] NORM $ CCLR: ALU[0] DEST[MA] NORM $ ALU[0] DEST[MEMSTO] NORM $ D[MA] ALU[D+1] DEST[MA] NORM $ D[MA] MASK[18.] COND[-OBUS=0] JUMP[. - 2] C600 $ POPJ NORM $ BYTE: D[CONST TP-MBOOT-GAP-DLY] LLOAD NORM $ B2: SPEC[IOB-IN] LOOP[B1] C550 $ D[CONST 10] ROT[6] LLOAD CYLEN[LONG] $ LOOP[.] CYLEN[LONG] $ SPEC[IOB-IN] CYLEN[LONG] $ MAPF[1] D[AR] ROT[43] MASK[21] COND[OBUS=0] JUMP[DONE] CYLEN[LONG] $ B5: SPEC[IOB-IN] D[CONST 0] DEST[AR] NORM $ MAPF[2] D[IOD] ALU[NOTD] DEST[HOLD] CYLEN[C800] $ D[MEM] ROT[33] MASK[1] COND[-OBUS=0] JUMP[B5] C550 $ JUMP[B3] NORM $ B1: D[IOD] ALU[NOTD] DEST[HOLD] MAPF[2] CYLEN[LONG] $ D[MEM] ROT[33] MASK[1] COND[-OBUS=0] JUMP[B2] C550 $ B3: SPEC[IOB-IN] D[AR] ALU[D+1] DEST[AR] NORM $ MAPF[2] SPEC[IOB-IN] D[IOD] ALU[NOTD] DEST[HOLD] C800 $ MAPF[1] D[MEM] ROT[31] C550 OBUS<0 JUMP[MBERR] $ ;TEST FOR GOOD PARITY IN BYTE. D[MEM] MASK[10] DEST[HOLD] POPJ NORM $ MBERR: JUMP[DONE] $ ;;D[CONST 0] DEST[MA] NORM JUMP[DONE] $ DONE: D[CONST 0] DEST[IOD] SPEC[IOB-OUT] CYLEN[LONG] $ .REPEAT 1 - STANSW [ D1: MAPF[2] D[CONST 0] DEST[DEV-ADR] SPEC[IOB-IN] CYLEN[LONG] $ ;CHECK START AND CONT SWITCHES. RD NEXT FILE ON CONT MAPF[4] D[IOD] ROT[5] MASK[2] DEST[AR] COND[OBUS=0] JUMP[D1] CYLEN[LONG] $ ; ... START MAIN MICROCODE ON START SWITCH. D[AR] MASK[1] COND[-OBUS=0] JUMP[MSTART] C550 $ SPEC[IOB-OUT] NORM $ MAPF[4] JUMP[MBOOT] CYLEN[LONG] $ ];.REPEAT 1 - STANSW .REPEAT STANSW [ MAPF[2] D[CONST 0] DEST[DEV-ADR] SPEC[IOB-IN] CYLEN[LONG] $ ;CHECK START AND CONT SWITCHES. RD NEXT FILE ON CONT MAPF[4] D[IOD] DEST[AR] SPEC[IOB-OUT] LONG $ ;Fetch switches. Clear old ones MAPF[4] SWTEST[3 JUMP NOAUTO] $ ;STOP - Don't auto-load D[CONST (120 / 2)] ROT[1] DEST[MA] $ ;Fetch starting address D[MEM] MASK[22] DEST[PC] jump[mstart] LONG $ ;Set starting address ;We can't auto-start yet because Reset code isn't a subroutine. NOAUTO: MAPF[4] SWTEST[5 JUMP MSTART] $ ;START - Start ucode SWTEST[4 JUMP MBOOT] $ ;CONT - Read next file on tape ;Nothing happening. Wait some more. D[CONST 0] DEST[DEV-ADR] SPEC[IOB-IN] CYLEN[LONG] $ ;Check START and CONT switches. MAPF[4] D[IOD] DEST[AR] SPEC[IOB-OUT] JUMP[NOAUTO] LONG $ ;Fetch switches. Clear old ones ];.REPEAT STANSW .RELOC ] ;END OF SLOW 125 IPS TAPE CODE .DEFINE FOOLIST[] [ XLIST ] LIST